package su.myspringapps.onlineschool.repository;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import su.myspringapps.onlineschool.entity.Course;
import su.myspringapps.onlineschool.entity.Student;
import su.myspringapps.onlineschool.entity.Subscription;
import su.myspringapps.onlineschool.entity.SubscriptionKey;

import java.util.Date;
import java.util.List;

import static org.hibernate.resource.transaction.spi.TransactionStatus.ACTIVE;
import static org.hibernate.resource.transaction.spi.TransactionStatus.MARKED_ROLLBACK;

/**
 * Класс SubscriptionRepository
 * <p/>
 * Отвечает за работу, связанную с сущностью {@link Subscription}
 * <p/>
 *
 * @author petr.mikhailin
 * created 26.05.2024 15:41
 */
@Repository
public class SubscriptionRepository {

    private final SessionFactory sessionFactory;

    @Autowired
    public SubscriptionRepository(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void subscribeStudentToCourse(Student student, Course course) throws Exception {
        Subscription subscription = new Subscription();
        SubscriptionKey subscriptionKey = new SubscriptionKey();
        subscriptionKey.setStudentId(student.getId());
        subscriptionKey.setCourseId(course.getId());
        subscription.setSubscriptionKey(subscriptionKey);
        subscription.setStudent(student);
        subscription.setCourse(course);
        subscription.setSubscriptionDate(new Date());
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.saveOrUpdate(subscription);
        } catch (Exception e) {
            if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
                transaction.rollback();
            }
            throw e;
        } finally {
            transaction.commit();
            session.close();
        }
    }

    public void unsubscribeStudentFromCourse(Student student, Course course) throws Exception {
        SubscriptionKey subscriptionKey = new SubscriptionKey();
        subscriptionKey.setStudentId(student.getId());
        subscriptionKey.setCourseId(course.getId());
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.createQuery("DELETE Subscription WHERE student.id= :student_id AND course.id = :course_id")
                    .setParameter("student_id", student.getId()).setParameter("course_id", course.getId()).executeUpdate();
        } catch (Exception e) {
            if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
                transaction.rollback();
            }
            throw e;
        } finally {
            transaction.commit();
            session.close();
        }
    }

    public List<Subscription> findAll() throws Exception {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            return session.createQuery("FROM Subscription", Subscription.class).list();
        } catch (Exception e) {
            if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
                transaction.rollback();
            }
            throw e;
        } finally {
            transaction.commit();
            session.close();
        }
    }

}
